package com.hhkj.study.admin.resource.service.biz.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import com.hhkj.study.admin.resource.common.CommonValidateHandler;
import com.hhkj.study.admin.resource.entity.ResourceCourseDoc;
import com.hhkj.study.admin.resource.excel.ResourceCourseDocExcelRes;
import com.hhkj.study.admin.resource.model.podo.ResourceCourseDocDo;
import com.hhkj.study.admin.resource.model.podo.ResourceCourseDocPo;
import com.hhkj.study.admin.resource.model.req.ResourceCourseDocReq;
import com.hhkj.study.admin.resource.model.req.ResourceDocBatchImportReq;
import com.hhkj.study.admin.resource.model.res.ResourceCourseDocRes;
import com.hhkj.study.admin.resource.service.base.ResourceCourseDocService;
import com.hhkj.study.admin.resource.service.biz.ResourceCourseDocBizService;
import com.hhkj.study.admin.resource.service.extend.ResourceCourseDocExtendService;
import com.hhkj.study.common.cache.GlobalCache;
import com.hhkj.study.common.model.res.ExcelImportResultRes;
import com.ruoyi.common.base.biz.service.biz.BaseBizServiceImpl;
import com.ruoyi.common.cont.SysConst;
import com.ruoyi.common.enums.DictCodeEnum;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.excl.utils.ExcelUtils;
import com.ruoyi.common.utils.file.FileUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* ResourceCourseDocBizServiceImpl
*
* @author SERVER
* @since 2024-09-06
*/
@Service
public class ResourceCourseDocBizServiceImpl extends BaseBizServiceImpl<ResourceCourseDoc, ResourceCourseDocReq, ResourceCourseDocRes, ResourceCourseDocDo, ResourceCourseDocPo, ResourceCourseDocService, ResourceCourseDocExtendService> implements ResourceCourseDocBizService {

    @Resource
    private GlobalCache globalCache;

    @Resource
    private CommonValidateHandler commonValidateHandler;

    @Override
    protected void afterPage(List<ResourceCourseDocRes> resourceDocResList) {
        assignDoc(resourceDocResList);
    }

    @Override
    protected void afterList(List<ResourceCourseDocRes> resourceDocResList) {
        assignDoc(resourceDocResList);
    }

    @Override
    protected void afterGetById(ResourceCourseDocRes resourceCourseDocRes) {
        assignDoc(Lists.newArrayList(resourceCourseDocRes));
    }

    @Override
    protected void beforeSave(ResourceCourseDocReq resourceCourseDocReq) {
        checkNameUnique(resourceCourseDocReq);
        if (StrUtil.isNotBlank(resourceCourseDocReq.getUrl())) {
            long fileSize = FileUtils.getFileSize(resourceCourseDocReq.getUrl());
            resourceCourseDocReq.setSize(fileSize);
        }
    }



    @Override
    protected void beforeUpdate(ResourceCourseDocReq resourceCourseDocReq) {
        ResourceCourseDoc resourceCourseDoc = this.getExtendService().getByIdNotNull(resourceCourseDocReq.getId());
        if (!StrUtil.equals(resourceCourseDoc.getName(), resourceCourseDocReq.getName())) {
            checkNameUnique(resourceCourseDocReq);
        }
        // 如果修改了资料内容更新资料大小
        if (!StrUtil.equals(resourceCourseDoc.getUrl(), resourceCourseDocReq.getUrl())) {
            long fileSize = FileUtils.getFileSize(resourceCourseDocReq.getUrl());
            resourceCourseDocReq.setSize(fileSize);
        }
    }

    /**
     * 检验名称的唯一性
     * @param resourceCourseDocReq
     */
    private void checkNameUnique(ResourceCourseDocReq resourceCourseDocReq) {
        ResourceCourseDoc courseDoc = this.getExtendService().getByNameCourseType(resourceCourseDocReq.getName(), resourceCourseDocReq.getCourseType());
        if (ObjectUtil.isNotNull(courseDoc)) {
            throw new GlobalException(resourceCourseDocReq.getName() + "资料名称已存在");
        }
    }

    @Override
    public boolean updatePublishFlag(ResourceCourseDocReq req) {
        ResourceCourseDoc resourceCourseDoc = this.getExtendService().getByIdNotNull(req.getId());
        if (resourceCourseDoc.getPublishedFlag().equals(req.getPublishedFlag())) {
            throw new GlobalException(SysConst.Flag.IS.getFlag().equals(req.getPublishedFlag()) ?
                    "已上架" : "已下架");
        }
        LambdaUpdateWrapper<ResourceCourseDoc> docUpdate = new LambdaUpdateWrapper<>();
        docUpdate.eq(ResourceCourseDoc::getId, req.getId())
                .set(ResourceCourseDoc::getPublishedFlag, req.getPublishedFlag());
        return this.getService().update(docUpdate);
    }

    @Override
    public void export(ResourceCourseDocReq req, HttpServletResponse response) {
        List<ResourceCourseDocRes> courseDocResList = list(req);
        if (CollectionUtil.isEmpty(courseDocResList)) {
            throw new GlobalException("没有数据");
        }
        ExcelUtils.exportExcelRuoYi(response, BeanUtil.copyToList(courseDocResList, ResourceCourseDocExcelRes.class), ResourceCourseDocExcelRes.class, "资料列表", "资料列表");
    }

    @Override
    public ExcelImportResultRes importCourseDoc(MultipartFile file, HttpServletRequest request) {
        List<ResourceCourseDocExcelRes> excelResList = ExcelUtils.importExcelRuoYi(file, ResourceCourseDocExcelRes.class, 1);
        if (CollectionUtil.isEmpty(excelResList)) {
            throw new GlobalException("没有数据");
        }

        ExcelImportResultRes excelImportResultRes = commonValidateHandler.validate(excelResList, (name, courseType) -> ObjectUtil.isNotNull(this.getExtendService().getByNameCourseType(name, courseType)));
        if (CollectionUtil.isEmpty(excelImportResultRes.getErrorList())) {
            List<ResourceCourseDoc> resourceCourseDocList = BeanUtil.copyToList(excelResList, ResourceCourseDoc.class);
            if (CollectionUtil.isNotEmpty(resourceCourseDocList)) {
                resourceCourseDocList.forEach(doc -> {
                    if (ObjectUtil.isNull(doc.getSize())) {
                        doc.setSize(FileUtils.getFileSize(doc.getUrl()));
                    }
                });
                this.getService().saveBatch(resourceCourseDocList);
            }
        }
        return excelImportResultRes;
    }

    @Override
    public boolean importBatchCourseDoc(ResourceDocBatchImportReq req) {
        List<ResourceCourseDoc> resourceCourseDocList = req.getDocList().stream().map(doc -> {
            ResourceCourseDoc resourceCourseDoc = new ResourceCourseDoc();
            resourceCourseDoc.setCourseType(req.getCourseType());
            resourceCourseDoc.setType(req.getType());
            resourceCourseDoc.setName(doc.getFileName());
            resourceCourseDoc.setUrl(doc.getUrl());
            resourceCourseDoc.setSize(FileUtils.getFileSize(doc.getUrl()));
            resourceCourseDoc.setOriginFileName(doc.getFileName());
            return resourceCourseDoc;
        }).collect(Collectors.toList());
        return this.getService().saveBatch(resourceCourseDocList);
    }

    private void assignDoc(List<ResourceCourseDocRes> resourceDocResList) {
        Map<Long, String> dictMap = globalCache.cacheDictParentMap(Lists.newArrayList(DictCodeEnum.COURSE_TYPE.getCode(), DictCodeEnum.DOC_TYPE.getCode()));
        resourceDocResList.forEach(resourceDocRes -> {
            resourceDocRes.setCourseTypeName(dictMap.get(resourceDocRes.getCourseType()));
            resourceDocRes.setTypeName(dictMap.get(resourceDocRes.getType()));
        });
    }
}